#pragma once

#include <map>
#include <memory>
#include "Model/Mesh.h"
#include "Model/Scene.h"
#include "Model/MeshFactory.h"
#include "Gui/Panel.h"

class Application {
public: // Constructors
	Application();
	~Application();

public: // Members
	void run();
	
public: // GUI callbacks
	void onQuit();
	void onNewTable();
	void onNewRobot();
	void onNewCube();
	void onDeleteObject();
	void onWireframe();
	void onTranslateMode();
	void onRotateMode();
	void onScaleMode();
	void onNextObject();
	void onPrevObject();

public: // glutCallbacks
	void onRender();
	void onKeyboard( unsigned char ch, int x, int y );
	void onMotion( int x, int y );
	void onMouse( int button, int state, int x, int y );
	void onReshape( int w, int h );
	void onMenu( int idx );

public:
	static void render();
	static void keyboard( unsigned char, int, int );
	static void motion( int, int );
	static void mouse( int, int, int, int );
	static void reshape( int, int );
	static void menu( int );

private: // Non-copyable
	Application( const Application& );
	Application& operator = ( const Application& );

private: // Helper functions
	void setupMenu();
	void setupGui();

public: // Helper members
	// "User data" for glut windows
	static std::map<int, Application* const> instanceMap;

private: // Test
	int screenWidth;
	int screenHeight;
	std::shared_ptr<Gui::Panel> panel;
	Model::Scene scene;
	Model::MeshFactory factory;
	// std::shared_ptr<Model::Mesh> mesh;
	bool wireframe;
	int selectedObject;
	int tansformMode;
};